package com.example.demo.poc.example;

import com.googlecode.aviator.runtime.function.AbstractVariadicFunction;
import com.googlecode.aviator.runtime.type.AviatorNil;
import com.googlecode.aviator.runtime.type.AviatorObject;
import com.googlecode.aviator.runtime.type.AviatorRuntimeJavaType;
import com.googlecode.aviator.runtime.type.AviatorType;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

public class AviatorAVGFunction extends AbstractVariadicFunction {
    @Override
    public AviatorObject variadicCall(Map<String, Object> env, AviatorObject... args) {
        if (args == null || args.length == 0) {
            return AviatorNil.NIL;
        }

        Object o = getSumValue(env, args);
        int l = args.length;
        if (l == 1) {
            Object i = args[0].getValue(env);
            if (i.getClass().isArray()) {
                l = ((Object[]) i).length;
            } else if (i instanceof java.util.List) {
                l = ((List) i).size();
            }

            if (l < 1) {
                l = 1;
            }
        }
//        if(o instanceof Double){
            return AviatorRuntimeJavaType.valueOf((Double)(((Double)o)/l));
//        }else{
//            return AviatorRuntimeJavaType.valueOf((Long)(((Long)o)/l));
//        }
    }

    private Object getSumValue(Map<String, Object> env, AviatorObject... args) {
        if (args == null || args.length == 0) {
            return AviatorNil.NIL;
        }
        BigDecimal val = BigDecimal.valueOf(0L);
        boolean hasDouble = false;
        for (int i = 0; i < args.length; i++) {
            Object o = args[i].getValue(env);
            if (o instanceof Long) {
                val = val.add(BigDecimal.valueOf((Long) o));
            } else if (o instanceof Double) {
                hasDouble = true;
                val = val.add(BigDecimal.valueOf((Double) o));
            } else if (o.getClass().isArray()) {

                val = val.add(getSumValue((Object[]) o));

            } else if (o instanceof java.util.List) {
                val = val.add(getSumValue((List) o));
            }
        }
//        if (!hasDouble) {
//            return val.longValue();
//        } else {
            return val.doubleValue();
//        }
    }

    private BigDecimal getSumValue(Object[] o) {
        BigDecimal val = BigDecimal.valueOf(0L);
        if (o == null || o.length == 0) {
            return val;
        }
        for (int i = 0; i < o.length; i++) {
            if (o[i] instanceof Long) {
                val = val.add(BigDecimal.valueOf((Long) o[i]));
            } else if (o[i] instanceof Double) {
                val = val.add(BigDecimal.valueOf((Double) o[i]));
            }
        }
        return val;
    }

    private BigDecimal getSumValue(List o) {
        BigDecimal val = BigDecimal.valueOf(0L);
        if (o == null || o.size() == 0) {
            return val;
        }
        for (int i = 0; i < o.size(); i++) {
            if (o.get(i) instanceof Long) {
                val = val.add(BigDecimal.valueOf((Long) o.get(i)));
            } else if (o.get(i) instanceof Double) {
                val = val.add(BigDecimal.valueOf((Double) o.get(i)));
            }
        }

        return val;
    }

    @Override
    public AviatorType getAviatorType() {
        return AviatorType.Lambda;
    }

    @Override
    public String getName() {
        return "avg";
    }
}
